-- Lua Battle System - 配置加载器单元测试

-- 设置Lua路径
package.path = package.path .. ';src/?.lua;src/utils/?.lua;res/data/?.lua'

local TestFramework = require("src.utils.test_framework")
local Logger = require("utils.logger")
local TableUtils = require("utils.table_utils")
local ConfigLoader = require("utils.config_loader")

-- 创建ConfigLoader实例
local config_loader_instance = {}
for k, v in pairs(ConfigLoader) do
    if type(v) == "function" then
        config_loader_instance[k] = function(...)
            return v(config_loader_instance, ...)
        end
    else
        config_loader_instance[k] = v
    end
end

local function run_tests()
    local suite = TestFramework.create_suite("ConfigLoader Unit Tests")

    -- 测试套件设置
    local function setup()
        -- 创建测试配置文件目录和文件
        local test_config_dir = "/tmp/lua_battle_test_config/"
        os.execute("mkdir -p " .. test_config_dir)

        -- 创建测试配置文件
        local test_config_file = io.open(test_config_dir .. "test_config.lua", "w")
        if test_config_file then
            test_config_file:write([[
return {
    name = "test_config",
    version = "1.0.0",
    settings = {
        debug = true,
        max_players = 10,
        game_mode = "battle"
    },
    items = {
        {id = 1, name = "sword", damage = 10},
        {id = 2, name = "shield", defense = 5}
    }
}
]])
            test_config_file:close()
        end

        -- 创建依赖配置文件
        local dependency_file = io.open(test_config_dir .. "dependency_config.lua", "w")
        if dependency_file then
            dependency_file:write([[
return {
    dependency_name = "test_dependency",
    version = "1.0.0",
    requires = {"test_config"}
}
]])
            dependency_file:close()
        end

        return test_config_dir
    end

    -- Teardown函数：清理测试环境
    local function teardown(test_config_dir)
        if test_config_dir then
            os.execute("rm -rf " .. test_config_dir)
        end
    end

    local test_config_dir

    suite:setup(function()
        test_config_dir = setup()
    end)

    suite:teardown(function()
        teardown(test_config_dir)
    end)

    -- 测试1：模块加载
    suite:add_test("Module loading", function()
        TestFramework.Assert.is_type("table", ConfigLoader, "ConfigLoader should be a table")
        TestFramework.Assert.is_type("table", config_loader_instance, "ConfigLoader instance should be a table")
        TestFramework.Assert.is_type("table", Logger, "Logger should be a table")
    end)

    -- 测试2：ConfigLoader初始化
    suite:add_test("ConfigLoader initialization", function()
        if not config_loader_instance then
            print("Skipping ConfigLoader tests - module not loaded")
            return
        end

        -- 测试默认初始化
        local result = config_loader_instance:init()
        TestFramework.Assert.is_true(result, "ConfigLoader init should return true")

        -- 测试带配置初始化
        local custom_config = {
            config_path = test_config_dir,
            cache_config = {
                enable_caching = false
            }
        }
        result = config_loader_instance:init(custom_config)
        TestFramework.Assert.is_true(result, "ConfigLoader init with custom config should return true")
        TestFramework.Assert.equals(test_config_dir, config_loader_instance.config_path, "Custom config path should be set")
    end)

    -- 测试3：配置缓存机制
    suite:add_test("Configuration caching", function()
        if not config_loader_instance then
            print("Skipping ConfigLoader tests - module not loaded")
            return
        end

        -- 重置缓存
        config_loader_instance.configs = {}
        config_loader_instance.metadata = {}

        -- 设置测试配置路径
        config_loader_instance.config_path = test_config_dir

        -- 第一次加载配置（应该从文件加载）
        local config1 = config_loader_instance.load_config("test_config")
        TestFramework.Assert.is_not_nil(config1, "Config should be loaded successfully")
        TestFramework.Assert.equals("test_config", config1.name, "Config name should match")

        -- 第二次加载配置（应该从缓存加载）
        local config2 = config_loader_instance.load_config("test_config")
        TestFramework.Assert.equals(config1, config2, "Second load should return cached config")

        -- 检查缓存状态
        TestFramework.Assert.table_contains_key(config_loader_instance.configs, "test_config", "Config should be cached")
    end)

    -- 测试4：配置文件路径构建
    suite:add_test("Configuration file path building", function()
        if not config_loader_instance then
            print("Skipping ConfigLoader tests - module not loaded")
            return
        end

        config_loader_instance.config_path = "/test/path/"
        local full_path = config_loader_instance._build_config_path("test_config")
        TestFramework.Assert.equals("/test/path/test_config.lua", full_path, "Config path should be built correctly")
    end)

    -- 测试5：配置依赖关系
    suite:add_test("Configuration dependencies", function()
        if not config_loader_instance then
            print("Skipping ConfigLoader tests - module not loaded")
            return
        end

        -- 重置依赖关系
        config_loader_instance.dependencies = {}
        config_loader_instance.config_path = test_config_dir

        -- 模拟添加依赖关系
        config_loader_instance.add_dependency("test_config", {"dependency_config"})

        -- 检查依赖关系是否正确记录
        TestFramework.Assert.table_contains_key(config_loader_instance.dependencies, "test_config", "Dependency should be recorded")
    end)

    -- 测试6：热重载功能
    suite:add_test("Hot reload functionality", function()
        if not config_loader_instance then
            print("Skipping ConfigLoader tests - module not loaded")
            return
        end

        -- 启用热重载
        config_loader_instance.hot_reload_config.enable_hot_reload = true
        config_loader_instance.hot_reload_config.check_interval = 1

        -- 测试热重载启动
        local result = config_loader_instance.enable_hot_reload()
        TestFramework.Assert.is_true(result, "Hot reload should enable successfully")

        -- 测试热重载停止
        result = config_loader_instance.disable_hot_reload()
        TestFramework.Assert.is_true(result, "Hot reload should disable successfully")
    end)

    -- 测试7：配置验证
    suite:add_test("Configuration validation", function()
        if not config_loader_instance then
            print("Skipping ConfigLoader tests - module not loaded")
            return
        end

        local valid_config = {
            name = "test",
            version = "1.0.0",
            type = "skill"
        }

        local result = config_loader_instance.validate_config(valid_config, "skill")
        TestFramework.Assert.is_true(result, "Valid config should pass validation")

        -- 测试无效配置
        local invalid_config = {
            name = "", -- 空名称
            type = "skill"
        }

        result = config_loader_instance.validate_config(invalid_config, "skill")
        TestFramework.Assert.is_false(result, "Invalid config should fail validation")
    end)

    -- 测试8：错误处理
    suite:add_test("Error handling", function()
        if not config_loader_instance then
            print("Skipping ConfigLoader tests - module not loaded")
            return
        end

        -- 测试加载不存在的配置文件
        config_loader_instance.config_path = "/nonexistent/path/"
        local config = config_loader_instance.load_config("nonexistent_config")
        TestFramework.Assert.is_nil(config, "Loading nonexistent config should return nil")

        -- 测试加载无效的配置文件
        config_loader_instance.config_path = test_config_dir
        local invalid_config_file = io.open(test_config_dir .. "invalid_config.lua", "w")
        if invalid_config_file then
            invalid_config_file:write("invalid lua syntax here !!!")
            invalid_config_file:close()

            local config = config_loader_instance.load_config("invalid_config")
            TestFramework.Assert.is_nil(config, "Loading invalid config should return nil")
        end
    end)

    -- 运行测试套件
    suite:run()

    -- 返回测试结果
    return TestFramework.get_stats().failed == 0
end

-- 导出测试函数
return {
    run_tests = run_tests
}